<template>
    <el-form-item :label="item.label" :prop="item.key" :labelWidth="item.labelWidth || labelWidth">
        <OnClickOutside class="w" @trigger="close">
            <el-select class="tw_custom_select w" :popper-class="item.key" ref="selectRef"
                       v-model="formData[item.key]" :placeholder="item.placeholder|| `请选择${item.label}`" :multiple="item.multiple"
                       :collapse-tags="item.collapseTags!==false" collapse-tags-tooltip :clearable="item.clearable !== false"
                       :disabled="item.disabled" :filterable="item.remote" v-loadMore="loadNextData" :teleported="false"
                       :default-first-option="item.defaultFirstOption"
                       :remote="item.remote" remote-show-suffix
                       :allow-create="item.allowCreate"
                       :multiple-limit="item.multipleLimit || 0"
                       :reserve-keyword="item.remote" :remote-method="remoteMethod" @change="selectChange"
                       @visible-change="getSelectOption($event, item)"
                       @blur="blurSelect"
                       @focus="onFocusSelect"
                       @clear="clearKeyword">
                <template v-if="item.children">
                    <div :class="item.showHandle?'pt32':''">
                        <div class="views w" v-if="item.showHandle"><el-button type="primary" text="primary" @click="handleReverse">反选</el-button><el-button type="primary" text="primary" @click="handleAllOrNot">全选/全不选</el-button></div>
                        <el-option
                            v-for="(tag, i) in item.children"
                            :key="i"
                            :label="tag[item.props?.label ?? 'label']"
                            :value="tag[item.props?.value ?? 'value']"
                        />
                    </div>
                    
                </template>
            </el-select>
        </OnClickOutside>
    </el-form-item>
</template>

<script setup lang="ts">
import {commonApi} from "@/api/common";
import { OnClickOutside } from '@vueuse/components'
import {getCurrentInstance} from "vue";
import {debounce} from "@/utils";

let { proxy} = getCurrentInstance()
const {formData, item, lists} = defineProps({
    formData: Object,
    item: Object,
    lists: Array
})
let selectRef = $ref(null)
let loading = $ref(false)
let pageParams = {}
const close = () => {
    selectRef.blur()
}

if (item.filter) {
    item.children = []
} else if (item.children) {
    item.children = item.children
}
if (item.all) {
    item.children.unshift({ label: '全部', value: undefined })
}
// let lists = $ref([])
const remoteMethod = debounce((query: string) => {
    if (!item.remote) return
    if(item.multiple || query){
        item.params.pageNumber = 1
        pageParams['keyword'] = query
        if(item.keywordKey) {
            pageParams[item.keywordKey] = query
        }
        loadData()
    }
    // else {
    //     item.children = []
    // }
},500)

// 反选
const handleReverse = () =>{
    let valueKey = item.props?.value ?? 'value'
    let hasSelectList = proxy.$_.cloneDeep(formData[item.key]) //被选中的数据
    let remainArr = proxy.$_.cloneDeep(formData[item.key]) //当前
    let arrList = []
    item.children.forEach((curObj,index)=>{
        if(!hasSelectList.includes(curObj[valueKey])){
            arrList.push(curObj[valueKey])
        }else{
            remainArr.splice(remainArr.indexOf(curObj[valueKey]), 1)
        }
    })
    formData[item.key] = [...remainArr,...arrList]
    let val = formData[item.key]
    if (item.change) {
        item.change(val, formData, item)
    }
    emits('tapClick', 'selectChange', {val, item, children: item.children})
}

// 全选
const handleAllOrNot = () =>{
    let valueKey = item.props?.value ?? 'value'
    let hasSelectList = proxy.$_.cloneDeep(formData[item.key])
    let flag = false //下拉的children是否有没被选中的 有就true 走全选 否则全不选
    let curSelect = []//当前下拉的children被选中,
    let curRemain = []//当前下拉的children未被选中
    for(let i=0;i<item.children.length;i++){
        let curObj = item.children[i]
        if(!hasSelectList.includes(curObj[valueKey])){
            curRemain.push(curObj[valueKey])
            flag = true
        }else{
            curSelect.push(curObj[valueKey])
        }
    }
    if(flag){ //全选
        formData[item.key] = [...hasSelectList,...curRemain]  //将当前未被选中的数据加到选中的里面
    } else{ //全不选
        let newArr =[]
        hasSelectList.forEach((cur)=>{
            if(!curSelect.includes(cur)) newArr.push(cur)
        })
        formData[item.key] = newArr
    }
    let val = formData[item.key]
    if (item.change) {
        item.change(val, formData, item)
    }
    emits('tapClick', 'selectChange', {val, item, children: item.children})
}

const clearKeyword = ()=>{
    pageParams['keyword'] = ''
    if(item.keywordKey) {
        pageParams[item.keywordKey] = ''
    }
    loadData()
}
interface Res {
    rows?: Array<object>,
    list?: Array<object>,
}
const loadData = () => {
    if (item.url) {
        loading = true
        let params = {
            pageNumber: 1
        }
        if(item.params){
            params = item.params
        }
        if (params.pageNumber) {
            params.pageNumber = 1
        }
        if(formData[item.key] && item.method == 'post'){
            if(!item.multipleLimit) {
                params['selectCodes'] = [formData[item.key]]
            }else {
                params['selectCodes'] = formData[item.key]
            }
        }
        params = {...params, ...pageParams}
        commonApi(item.url, params, item.method).then(res => {
            loading = false
            if (res && res instanceof Array) {
                item.children = res
            } else {
                let list = (res as unknown as Res).rows
                if ( list && list instanceof Array) {
                    item.children = list
                }
            }
            if (item.params.pageNumber) {
                item.params.pageNumber++
            }
    
            // 加载成功后事件回调
            if(item.loadData){
                item.loadData(res)
            }
        }).catch(() => {
            loading = false
        })
    }
}

const blurSelect = (val)=>{
    // setTimeout(()=>{
    //     selectRef.blur()
    // },10)
    if(!formData[item.key]){
        emptyKeyword()
        if(item.defaultValue !== undefined) {
            formData[item.key] = item.defaultValue
        }
        loadData()
    }
}

// 仅仅清空keyword
const emptyKeyword = () => {
    pageParams['keyword'] = ''
    if(item.keywordKey) {
        pageParams[item.keywordKey] = ''
    }
}

const onFocusSelect = (val) => {
    if(item.loadDataOnFocus) {
        loadData()
    }
}

const getSelectOption = (pType)=>{
    if (pType) {
        // 远程搜索时控制icon样式
        // pObject.visibleChange = true
        if(!item.children){
            item.children = []
        }
        if(item.children.length == 0){
            loadData()
        }
    } else {
        // pObject.visibleChange = false
    }
}
loadData()


const loadNextData = () => {
    if (item.url && item.loadMore) {
        if (!loading) {
            loading = true
            let params = item.params || {}
            params = {...params, ...pageParams}
            commonApi(item.url, params, item.method).then(res => {
                loading = false
                item.params.pageNumber++
                if (res && res instanceof Array) {
                    item.children = [...item.children, ...res]
                } else {
                    let list = (res as unknown as Res).rows
                    if ( list && list instanceof Array) {
                        item.children = [...item.children, ...list]
                        console.info('res data is no Array, use res.rows')
                    }
                }
                // item.children = item.children.concat(res)
                
            }).catch(() => {
                loading = false
            })
        }
    }
}

let emits = defineEmits(['tapClick'])
const selectChange = (val) => {
    if (item.arrChangeKey) {
        item.arrChangeKey.forEach(key => {
            formData[key] = val
        })
        emits('tapClick', 'reset', item)
    }
    
    if(item.relyOnData){
        item.relyOnData.forEach(item=>{
            lists.forEach(tag=>{
                if(item.key == tag.key){
                    formData[tag.key] = ''
                    tag.params[item.value] = val
                    if((!item.clearChildren) || (item.clearChildren === true)){
                        tag.children = []
                    }
                }
            })
        })
    }
    
    if (item.change) {
        item.change(val, formData, item)
    }
    emits('tapClick', 'selectChange', {val, item, children: item.children})
}

const reset = () => {
    loadData()
}

defineExpose({reset, loadData, item})
// const emit = defineEmits(['update:name'])
</script>

<style scoped lang="scss">
.tw_custom_select {
    :deep(.el-select__tags), :deep(.el-select__selection) { flex-wrap: nowrap; white-space: nowrap;}
}
.views{
    position: absolute; top: 0; background: #fff; z-index: 999999999;padding: 0 32px 0 20px;
    button{ padding: 0; }
}
.pt32{
    padding-top: 32px;
}
</style>


<!--<template>-->
<!--    <el-input v-model="name" />-->
<!--    {{name}}-->
<!--</template>-->

<!--<script setup lang="ts">-->
<!--const { name } =  defineProps({-->
<!--    name:String-->
<!--})-->
<!--console.log(name);-->

<!--const emit = defineEmits(['update:name'])-->
<!--</script>-->

<!--<style scoped lang="scss">-->

<!--</style>-->
